import datetime
import json

from django import http
from django.db import models
from django.shortcuts import render
from django.views import View

from apps.orders.models import OrderGoods
from utils.response_code import RETCODE
from .models import SKU, GoodsVisitCount
from apps.contents.utils import get_categories
from apps.goods.models import GoodsCategory
from .utils import get_breadcrumb
from .contants import GOODS_LIST_LIMIT
import logging
logger = logging.getLogger('django')


'''
前端逻辑
传递分类id, 分页id, 排序

后端逻辑
1. 先实现面包屑
    获取当前商品的分类
    根据分类的自关联信息来判断分类所处的级别
    当前分类没有parent 最顶层的
    当前分类没有子分类subs 最底层的
2. 再获取列表数据
    先获取数据
    再排序
    再分页

请求方式和路径
GET			/list/(?P<category_id>\d+)/(?P<page_num>\d+)/?sort=排序方式
'''

class ListView(View):
    def get(self, request, category_id, page_num):
        # 1. 先实现面包屑
        try:
            # 判断category_id是否正确
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseBadRequest('GoodsCategory does not exist')

        # 查询商品频道
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(category)

        # 2. 再排序
        # 接受sort参数, 如果用户不传, 就是默认排序(default)
        sort = request.GET.get('sort', 'default')

        # 按照排序规则查询该分类商品的SKU信息
        if sort == 'price':
            # 按价格降序
            sort_field = '-price'
        elif sort == 'hot':
            # 按照销量降序
            sort_field = '-sales'
        else:
            # 价格和销量之外的排序方式都归类为默认排序
            sort = 'default'
            sort_field = 'create_time'

        # 对所有数据进行排序
        skus = SKU.objects.filter(category=category).order_by(sort_field)

        # 3. 再分页
        from django.core.paginator import Paginator
        # 创建分页类
        paginator = Paginator(skus, GOODS_LIST_LIMIT)

        try:
            # 获取每页商品数据
            page_skus = paginator.page(page_num)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseBadRequest('empty page')
        # 获取列表页总页数
        total_page = paginator.num_pages

        # 返回数据
        context = {
            'categories': categories,   # 频道分类
            'breadcrumb': breadcrumb,   # 面包屑导航
            'sort': sort,               # 排序字段
            'category': category,       # 第三级分类
            'page_skus': page_skus,     # 分页后数据
            'total_page': total_page,   # 总页数
            'page_num': page_num,       # 当前页码
        }

        return render(request, 'list.html', context)

'''
前端逻辑
    传递category_id

后端逻辑
    # 1. 获取category_id, 根据类别排序, 再进行获取指定数据
    # 2.  将数据转化为字典
    # 3. 使用json格式返回响应

请求方式和路径
POST         /hot/(?P<category_id>\d+)/
'''
# 定义一个类, 处理热销商品排序业务
class HotView(View):
    def get(self, request, category_id):

        try:
            # 判断category是否存在
            category = GoodsCategory.objects.get(pk=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseBadRequest({'code': RETCODE.NODATAERR, 'errmsg': '该分类不存在'})

        # 1. 获取category_id, 根据类别排序, 再进行获取指定数据
        # 根据商品销量倒序排列
        skus = SKU.objects.filter(category_id=category_id).order_by('-sales')[:2]

        # 2.  将数据转化为字典
        hot_skus = []
        for sku in skus:
            hot_skus.append({
                'id': sku.id,
                'default_image_url': sku.default_image.url,
                'name': sku.name,
                'price': sku.price
            })
        # 3. 使用json格式返回响应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'hot_skus':hot_skus})



# 定义一个类, 处理商品详情页展示
class DetailView(View):

    def get(self,request,sku_id):

        # 获取当前sku的信息
        try:
            sku = SKU.objects.get(id=sku_id)
        except SKU.DoesNotExist:
            return render(request, '404.html')

        # 查询商品频道分类
        categories = get_categories()
        # 查询面包屑导航
        breadcrumb = get_breadcrumb(sku.category)

        # 构建当前商品的规格键
        sku_specs = sku.specs.order_by('spec_id')
        sku_key = []
        for spec in sku_specs:
            sku_key.append(spec.option.id)
        # 获取当前商品的所有SKU
        skus = sku.spu.sku_set.all()
        # 构建不同规格参数（选项）的sku字典
        spec_sku_map = {}
        for s in skus:
            # 获取sku的规格参数
            s_specs = s.specs.order_by('spec_id')
            # 用于形成规格参数-sku字典的键
            key = []
            for spec in s_specs:
                key.append(spec.option.id)
            # 向规格参数-sku字典添加记录
            spec_sku_map[tuple(key)] = s.id
        # 获取当前商品的规格信息
        goods_specs = sku.spu.specs.order_by('id')
        # 若当前sku的规格信息不完整，则不再继续
        if len(sku_key) < len(goods_specs):
            return
        for index, spec in enumerate(goods_specs):
            # 复制当前sku的规格键
            key = sku_key[:]
            # 该规格的选项
            spec_options = spec.options.all()
            for option in spec_options:
                # 在规格参数sku字典中查找符合当前规格的sku
                key[index] = option.id
                option.sku_id = spec_sku_map.get(tuple(key))
            spec.spec_options = spec_options

        # 渲染页面
        context = {
            'categories': categories,
            'breadcrumb': breadcrumb,
            'sku': sku,
            'specs': goods_specs,
        }

        return render(request,'detail.html',context)



'''
前端逻辑
    传递分类id

后端逻辑
    1.接收分类id
    2.先判断当天的当前的分类数据是否存在
    3.如果存在则计数+1
    4.如果不存在则添加一条记录
    5.返回相应

请求方式和路径
POST	   detail/visit/(?P<category_id>\d+)/
'''
# 定义一个类, 处理统计分类商品访问量
class DetailVisitView(View):

    def post(self, request, category_id):

        # 1.接收分类id
        try:
            category = GoodsCategory.objects.get(id=category_id)
        except GoodsCategory.DoesNotExist:
            return http.HttpResponseBadRequest('缺少必传参数')

        # 2.先判断当天的当前的分类数据是否存在
        # 获取当天的日期
        from django.utils import timezone
        today = timezone.localdate()
        try:
            # 查询今天该类别的商品的访问量
            gvc = GoodsVisitCount.objects.get(category=category, date=today)
        except GoodsVisitCount.DoesNotExist:
            # 3.如果不存在则添加一条记录
            GoodsVisitCount.objects.create(category=category,
                                           date=today,
                                           count=1)
        else:
            # 4.如果存在则计数+1
            gvc.count += 1
            gvc.save()

        # 5.返回相应
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK'})


# 商品详情展示评价
class GoodsCommentView(View):
    def get(self, request, sku_id):
        # 获取被评价的订单商品信息
        order_goods_list = OrderGoods.objects.filter(sku_id=sku_id,
                                                     is_commented=True).order_by('-create_time')
        # 评价商品列表
        goods_comment_list = []
        for order_goods  in order_goods_list:
            # 获取用户名
            username = order_goods.order.user.username
            goods_comment_list.append({
                # 对用户名隐藏显示
                'username': username[0] + '****' + username[-1] if order_goods.is_anonymous else username,
                # 评价内容
                'comment': order_goods.comment,
                # 评价分数
                'score': order_goods.score
            })

        return http.JsonResponse({'code':RETCODE.OK, 'errmsg':'OK', 'goods_comment_list': goods_comment_list})




